<?php
declare (strict_types=1);

namespace app\api\middleware;

use app\common\model\Config;
use app\common\tool\Result;
use think\facade\Cache;
use app\common\model\User;
use think\exception\HttpResponseException;

class Verify
{
    public function handle($request, \Closure $next)
    {
        $system = Cache::get('system');
        if (empty($system)) {
            $system = Config::lists();
            Cache::set('system', $system);
        }
        if ($system['system_status'] != 1) {
            $this->friendlyError(202, '系统维护中');
        }
        $request->system = $system;
        if ($request->isPost()) {
            $result = $this->verifyFrequent($request);
            if (!$result) {
                $this->friendlyError(-1, '您的操作过于频繁，请稍后再试！');
            }
        }
        $result = $this->verifyToken($request);
        if ($result['code'] !== 1) {
            $this->friendlyError($result['code'], $result['msg']);
        }
        $request->user = $result['result'];

        return $next($request);
    }

    protected function verifyFrequent($request): bool
    {
        $token = $request->header('token');
        $array = json_encode(['token' => $token, 'controller' => $request->controller(), 'action' => $request->action()]);
        if (Cache::get($array)) {
            return false;
        }
        Cache::set($array, 1, 1);

        return true;
    }

    protected function verifyToken($request): array
    {
        $token = $request->header('token');
        if (empty($token)) return ['code' => 201, 'msg' => '请登录'];
        $user = User::where(['token' => $token])->find();
        if (empty($user)) return ['code' => 201, 'msg' => '登录已过期'];
        if ($user->is_lock) return ['code' => 201, 'msg' => '账号已锁定'];

        return ['code' => 1, 'result' => $user];
    }

    public function friendlyError($code, $msg)
    {
        $result = [
            'code' => $code,
            'msg'  => $msg
        ];
        $response = Result::fastReturn($result);

        throw new HttpResponseException($response);
    }
}